//
//	File: OyDirect3D9_MaterialSystem.cpp
//

#include "OyDirect3D9_MaterialSystem.h"
#include "MaterialSystem\Material.h"
#include "MaterialSystem\MaterialProperties.h"


OyMaterialSystem::D3D9MaterialInfo::D3D9MaterialInfo()
{
	m_material = new CMaterial();
}

OyMaterialSystem::D3D9MaterialInfo::D3D9MaterialInfo( char* MaterialStr )
{
	m_material = new CMaterial( MaterialStr );
}

void OyMaterialSystem::D3D9MaterialInfo::CloneMaterial( const D3D9MaterialInfo& _MaterialInfo )
{ 
	m_material->Clone( _MaterialInfo.m_material );
}

void OyMaterialSystem::D3D9MaterialInfo::Reset()
{
	if( m_material )
	{
		delete m_material;
		m_material = NULL;
	}
	m_material = new CMaterial();
}

OyMaterialSystem::~OyMaterialSystem()
{
	for( int i=0; i<m_materials.Count(); i++ )
	{
		if( m_materials[i].m_material )
		{
			delete m_materials[i].m_material;
			m_materials[i].m_material = NULL;
		}
	}
	for( int i=0; i<m_modifiers.Count(); i++ )
	{
		if( m_modifiers[i].m_material )
		{
			delete m_modifiers[i].m_material;
			m_modifiers[i].m_material = NULL;
		}
	}
}


void OyMaterialSystem::AddMaterial( char* MaterialStr )
{
	D3D9MaterialInfo& MatInfo = D3D9MaterialInfo(MaterialStr);
	if( !m_materials.Push( MatInfo ) )
	{
		m_materials.Resize(m_materials.Size() + INIT_MATERIALLIST_BEGIN_NUM);
		m_materials.Push( MatInfo );
	}
}

void OyMaterialSystem::AddModifier(  char* ModifierStr )
{
	D3D9MaterialInfo& ModInfo = D3D9MaterialInfo(ModifierStr);
	if( !m_modifiers.Push( ModInfo ) )
	{
		m_modifiers.Resize(m_modifiers.Size() + INIT_MATERIALLIST_BEGIN_NUM);
		m_modifiers.Push( ModInfo );
	}
}

void OyMaterialSystem::AddMaterial( D3D9MaterialInfo *pNewMaterialInfo )
{
	if( !m_materials.Push( *pNewMaterialInfo ) )
	{
		m_materials.Resize(m_materials.Size() + INIT_MATERIALLIST_BEGIN_NUM);
		m_materials.Push( *pNewMaterialInfo );
	}
}
void OyMaterialSystem::AddModifier( D3D9MaterialInfo *pNewModifierInfo )
{
	if( !m_modifiers.Push( *pNewModifierInfo ) )
	{
		m_modifiers.Resize(m_modifiers.Size() + INIT_MATERIALLIST_BEGIN_NUM);
		m_modifiers.Push( *pNewModifierInfo );
	}
}

void OyMaterialSystem::UpdateDynamicMaterials( float elapsedTime )
{
	AbstractMaterial::UpdateDynamicMaterials( elapsedTime );
}

void OyMaterialSystem::LoadGameMaterials()
{
	// Materials
	#include "MaterialSystem\MaterialString\opaque_base.h"
	AddMaterial( Material_opaque_base_String );
	#include "MaterialSystem\MaterialString\opaque_alphatest.h"
	AddMaterial( Material_opaque_alphatest_String );
	#include "MaterialSystem\MaterialString\transparent.h"
	AddMaterial( Material_transparent_String );

	#include "MaterialSystem\MaterialString\line.h"
	AddMaterial( Material_Line_String );
	#include "MaterialSystem\MaterialString\Font.h"
	AddMaterial( Material_Font_String );


	#include "MaterialSystem\MaterialString\custom.h"
	AddMaterial( Material_custom_String );



	// Modifiers
	//AddModifier( "withlight.mtl" );
	//AddModifier( "nolight.mtl" );
	//AddModifier( "wireframe.mtl" );
}

void OyMaterialSystem::LoadCustomMaterials( char* MaterialStr )
{
	D3D9MaterialInfo &Material_info = m_materials[eMaterial_Custom];
	if( Material_info.m_material != NULL )
	{
		delete Material_info.m_material;
		Material_info.m_material = NULL;
		m_materials.Pop();
	}

	AddMaterial( MaterialStr );
}

void OyMaterialSystem::CommitAdditionalMaterial(const struct D3D9MaterialInfo& MT, const struct OYSKIN_TYPE* pSkin )
{
	if( pSkin->nTextureID[0] != 0xFFFFFFFF )
	{
		// Texture
		MT.m_material->GetRenderPass(0)->AddProperty(new TextureProperty(pSkin->nTextureID[0], 0));
	}
}

void OyMaterialSystem::UpdateTextureMaterial(const struct D3D9MaterialInfo& MT, unsigned int texID, int unit)
{
	MT.m_material->GetRenderPass(0)->UpdateTexture(texID, unit);
}